package com.himaci.gtbattle.view;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;
import com.himaci.gtbattle.model.GameChar;
import com.himaci.gtbattle.model.Player;
import com.himaci.gtbattle.model.World;
import com.himaci.gtbattle.model.character.Archer;
import com.himaci.gtbattle.model.character.Mage;
import com.himaci.gtbattle.model.character.Priest;
import com.himaci.gtbattle.resource.Assets;

/**
 * Kelas WorldRenderer
 *
 * @author XNPSDN
 */
public class WorldRenderer {

    static final float FRUSTUM_WIDTH = 480f;
    static final float FRUSTUM_HEIGHT = 320f;
    private World world;
    private OrthographicCamera camera;
    private SpriteBatch batcher;
    // character set
    private Rectangle[][] playerRect;

    /**
     * Konstruktor
     * @param world World yang mau dirender
     */
    public WorldRenderer(World world, SpriteBatch batcher) {
	this.world = world;
	this.batcher = batcher;
	this.camera = new OrthographicCamera(FRUSTUM_WIDTH, FRUSTUM_HEIGHT);
	this.camera.position.set(FRUSTUM_WIDTH / 2, FRUSTUM_HEIGHT / 2, 1);

	playerRect = new Rectangle[3][3];
	playerRect[0][0] = new Rectangle(30, 210, 40, 80);
	playerRect[0][1] = new Rectangle(50, 140, 40, 80);
	playerRect[0][2] = new Rectangle(70, 70, 40, 80);
	playerRect[1][0] = new Rectangle(370, 210, 40, 80);
	playerRect[1][1] = new Rectangle(390, 140, 40, 80);
	playerRect[1][2] = new Rectangle(410, 70, 40, 80);
    }

    /**
     * Render current World, batcher sudah mulai
     */
    public void render() {
	camera.update();
	batcher.setProjectionMatrix(camera.combined);

	// draw the people
	for (int i = 0; i < 2; ++i) {
	    Player drawablePlayer = i == 0 ? world.player1 : world.player2;

	    for (int j = 0; j < 3; ++j) {
		GameChar drawableChar = drawablePlayer.characters[j];

		TextureRegion drawableImage = null;
		Rectangle drawablePosition = playerRect[i][j];
		if (drawableChar instanceof Archer) {
		    if (drawableChar.state == GameChar.STATE_READY) {
			drawableImage = Assets.getInstance().archerReady.getKeyFrame(drawableChar.stateTime, true);
		    } else if (drawableChar.state == GameChar.STATE_ATTACKING) {
			drawableImage = Assets.getInstance().archerAttack.getKeyFrame(drawableChar.stateTime, true);
		    } else if (drawableChar.state == GameChar.STATE_SKILLING) {
			drawableImage = Assets.getInstance().archerSpecial.getKeyFrame(drawableChar.stateTime, true);
		    } else if (drawableChar.state == GameChar.STATE_ATTACKED) {
			drawableImage = Assets.getInstance().archerReady.getKeyFrame(drawableChar.stateTime, true);
		    } else if (drawableChar.state == GameChar.STATE_SUPPORTED) {
			drawableImage = Assets.getInstance().archerReady.getKeyFrame(drawableChar.stateTime, true);
		    } else if (drawableChar.state == GameChar.STATE_DEAD) {
			drawableImage = Assets.getInstance().archerDead.getKeyFrame(drawableChar.stateTime, false);
		    }
		} else if (drawableChar instanceof Mage) {
		    if (drawableChar.state == GameChar.STATE_READY) {
			drawableImage = Assets.getInstance().mageReady.getKeyFrame(drawableChar.stateTime, true);
		    } else if (drawableChar.state == GameChar.STATE_ATTACKING) {
			drawableImage = Assets.getInstance().mageAttack.getKeyFrame(drawableChar.stateTime, true);
		    } else if (drawableChar.state == GameChar.STATE_SKILLING) {
			drawableImage = Assets.getInstance().mageSpecial.getKeyFrame(drawableChar.stateTime, true);
		    } else if (drawableChar.state == GameChar.STATE_ATTACKED) {
			drawableImage = Assets.getInstance().mageReady.getKeyFrame(drawableChar.stateTime, true);
		    } else if (drawableChar.state == GameChar.STATE_SUPPORTED) {
			drawableImage = Assets.getInstance().mageReady.getKeyFrame(drawableChar.stateTime, true);
		    } else if (drawableChar.state == GameChar.STATE_DEAD) {
			drawableImage = Assets.getInstance().mageDead.getKeyFrame(drawableChar.stateTime, false);
		    }
		} else if (drawableChar instanceof Priest) {
		    if (drawableChar.state == GameChar.STATE_READY) {
			drawableImage = Assets.getInstance().priestReady.getKeyFrame(drawableChar.stateTime, true);
		    } else if (drawableChar.state == GameChar.STATE_ATTACKING) {
			drawableImage = Assets.getInstance().priestAttack.getKeyFrame(drawableChar.stateTime, true);
		    } else if (drawableChar.state == GameChar.STATE_SKILLING) {
			drawableImage = Assets.getInstance().priestSpecial.getKeyFrame(drawableChar.stateTime, true);
		    } else if (drawableChar.state == GameChar.STATE_ATTACKED) {
			drawableImage = Assets.getInstance().priestReady.getKeyFrame(drawableChar.stateTime, true);
		    } else if (drawableChar.state == GameChar.STATE_SUPPORTED) {
			drawableImage = Assets.getInstance().priestReady.getKeyFrame(drawableChar.stateTime, true);
		    } else if (drawableChar.state == GameChar.STATE_DEAD) {
			drawableImage = Assets.getInstance().priestDead.getKeyFrame(drawableChar.stateTime, false);
		    }
		}

		// set the color
		if (drawableChar.state == GameChar.STATE_ATTACKED) {
		    batcher.setColor(Color.WHITE.r,
			    Color.WHITE.g * (1 - (drawableChar.stateTime / GameChar.ATTACKED_ANIM_TIME)),
			    Color.WHITE.b * (1 - (drawableChar.stateTime / GameChar.ATTACKED_ANIM_TIME)),
			    1);
		}
		if (drawableChar.state == GameChar.STATE_SUPPORTED) {
		    batcher.setColor(Color.WHITE.r * (1 - (drawableChar.stateTime / GameChar.ATTACKED_ANIM_TIME)),
			    Color.WHITE.g * (1 - (drawableChar.stateTime / GameChar.ATTACKED_ANIM_TIME)),
			    Color.WHITE.b,
			    1);
		}

		// render the image
		batcher.draw(drawableImage,
			i == 0 ? drawablePosition.x : (drawablePosition.x + drawablePosition.width),
			drawablePosition.y,
			i == 0 ? drawablePosition.width : -drawablePosition.width,
			drawablePosition.height);

		// set back the color
		if (drawableChar.state == GameChar.STATE_ATTACKED || drawableChar.state == GameChar.STATE_SUPPORTED) {
		    batcher.setColor(Color.WHITE.r, Color.WHITE.g, Color.WHITE.b, 1);
		}

		if (world.isReady()) {
		    drawProjectile();
		}
	    }
	}
    }

    /**
     * Kembaliannya char yang di touch
     * @param x Posisi x
     * @param y Posisi y
     * @return -1 apabila tidak ada, 1-3 player 1, 4-6 player 2
     */
    public int touchChar(float x, float y) {
	Vector3 touchPoint = new Vector3();
	camera.unproject(touchPoint.set(x, y, 0));

	if (playerRect[0][0].contains(touchPoint.x, touchPoint.y)) {
	    return 1;
	} else if (playerRect[0][1].contains(touchPoint.x, touchPoint.y)) {
	    return 2;
	} else if (playerRect[0][2].contains(touchPoint.x, touchPoint.y)) {
	    return 3;
	} else if (playerRect[1][0].contains(touchPoint.x, touchPoint.y)) {
	    return 4;
	} else if (playerRect[1][1].contains(touchPoint.x, touchPoint.y)) {
	    return 5;
	} else if (playerRect[1][2].contains(touchPoint.x, touchPoint.y)) {
	    return 6;
	}

	return -1;
    }

    /**
     * Menggambar panah diatas pointer
     * @param pointer Posisi pointer
     */
    public void drawCharPointer(int pointer) {
	camera.update();
	batcher.setProjectionMatrix(camera.combined);

	if (pointer >= 1 && pointer <= 3) {
	    batcher.draw(Assets.getInstance().charPointer,
		    playerRect[0][pointer - 1].x + 10,
		    playerRect[0][pointer - 1].y + playerRect[0][pointer - 1].height,
		    15,
		    15);
	} else if (pointer >= 4 && pointer <= 6) {
	    batcher.draw(Assets.getInstance().charPointer,
		    playerRect[1][pointer - 4].x + 10,
		    playerRect[1][pointer - 4].y + playerRect[0][pointer - 4].height,
		    15,
		    15);
	}
    }

    /**
     * Menggambar panah diatas pointer
     * @param pointer Posisi pointer
     */
    public void drawTargetPointer(int pointer) {
	camera.update();
	batcher.setProjectionMatrix(camera.combined);

	if (pointer >= 1 && pointer <= 3) {
	    batcher.draw(Assets.getInstance().targetPointer,
		    playerRect[0][pointer - 1].x + 15,
		    playerRect[0][pointer - 1].y + playerRect[0][pointer - 1].height - 5,
		    15,
		    15);
	} else if (pointer >= 4 && pointer <= 6) {
	    batcher.draw(Assets.getInstance().targetPointer,
		    playerRect[1][pointer - 4].x + 15,
		    playerRect[1][pointer - 4].y + playerRect[0][pointer - 4].height - 5,
		    15,
		    15);
	}
    }

    /**
     * Menggambar projectile
     */
    public void drawProjectile() {
	for (World.Projectile proj : world.projectile) {
	    float x = playerRect[proj.startPlayerID - 1][proj.startCharID].x
		    + ((playerRect[proj.targetPlayerID - 1][proj.targetCharID].x - playerRect[proj.startPlayerID - 1][proj.startCharID].x)
		    * (world.projectileTime / World.Projectile.PROJECTILE_TIME))
		    + (playerRect[proj.startPlayerID - 1][proj.startCharID].width / 2);
	    float y = playerRect[proj.startPlayerID - 1][proj.startCharID].y
		    + ((playerRect[proj.targetPlayerID - 1][proj.targetCharID].y - playerRect[proj.startPlayerID - 1][proj.startCharID].y)
		    * (world.projectileTime / World.Projectile.PROJECTILE_TIME))
		    + (playerRect[proj.startPlayerID - 1][proj.startCharID].height / 2);

	    // gambar sparta!!!
	    batcher.draw(Assets.getInstance().projectile, x, y, 10, 10);
	}
    }
}
